package com.mininglamp.hbga.service;

import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.mininglamp.hbga.adapter.BaseAdapter;
import com.mininglamp.hbga.util.AdapterHelper;
import com.mininglamp.hbga.util.ConfigHelper;
import com.mininglamp.hbga.util.ResponseHelper;
import com.mininglamp.hbga.util.response.MapResponse;
import com.mininglamp.hbga.util.response.Response;
import org.javatuples.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Api Router
 * 实现Api接口的路由功能，将多个调用接口或数据运算的适配器逻辑，集成并返回
 */
@RestController
@RequestMapping("/api")
public class RouterService {

    private static final Logger logger = LoggerFactory.getLogger(RouterService.class);

    /**
     * 服务入口
     *
     * @param serviceName 服务名
     * @param request
     * @return
     */
    @RequestMapping(value = "/service/{serviceName}")
    public Response service(@PathVariable("serviceName") String serviceName, HttpServletRequest request) {
        logger.info("处理服务：{}", serviceName);
        request.getParameterMap().entrySet().forEach(e ->
            logger.info("  请求参数：{} -> {}", e.getKey(), Arrays.asList(e.getValue()))
        );
        try {
            return doService(serviceName, request);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResponseHelper.Error("500", e.getMessage());
        }
    }

    /**
     * 处理请求的服务
     *
     * @param serviceName 服务名称
     * @param request     Http请求
     * @return
     * @throws Exception
     */
    public Response doService(String serviceName, HttpServletRequest request) throws Exception {
        List<String> adapterNames = Splitter.on(';').omitEmptyStrings().trimResults().splitToList(
            ConfigHelper.INSTANCE.getProperty("api.router.service." + serviceName, "")
        );

        MapResponse<String, Object> response = new MapResponse<>();

        ExecutorService service = Executors.newFixedThreadPool(adapterNames.size());

        List<Pair<String, Future>> futures = Lists.newArrayList();
        for (String adapterName : adapterNames) {
            BaseAdapter adapter = AdapterHelper.INSTANCE.adapterClass(adapterName).setRequest(request);
            Future future = service.submit(adapter);
            futures.add(Pair.with(adapterName, future));
        }
        for (Pair<String, Future> p : futures) {
            try {
                response.put(p.getValue0(), p.getValue1().get());
            } catch (InterruptedException | ExecutionException e) {
                logger.error("处理错误", e);
            }
        }

        service.shutdown();

        return ResponseHelper.OK(response);
    }

    /**
     * 获取已加载的适配器信息
     *
     * @return
     */
    @RequestMapping(value = "/adapters", method = RequestMethod.GET)
    public Response adapters() {
        return ResponseHelper.listObjResponse(AdapterHelper.INSTANCE.adapters());
    }

}
